
<template>
  <div class="accounting-container">
    <div class="page-header">
      <div class="header-title">
        <h2>会计核算</h2>
        <span class="subtitle">管理会计科目和账务处理</span>
      </div>
      <div class="header-actions">
        <el-button-group>
          <el-button type="primary" @click="createVoucher">
            <el-icon><DocumentAdd /></el-icon>新建凭证
          </el-button>
          <el-button @click="refreshData">
            <el-icon><Refresh /></el-icon>刷新
          </el-button>
        </el-button-group>
      </div>
    </div>

    <el-row :gutter="20">
      <!-- 左侧：会计科目树 -->
      <el-col :span="6">
        <el-card class="subject-card">
          <template #header>
            <div class="card-header">
              <span>会计科目</span>
              <el-button type="primary" link @click="addSubject">
                添加科目
              </el-button>
            </div>
          </template>

          <el-input
            v-model="subjectKeyword"
            placeholder="搜索科目"
            prefix-icon="Search"
            clearable
            class="mb-3"
          />

          <el-tree
            ref="subjectTreeRef"
            :data="subjectTree"
            :props="defaultProps"
            :filter-node-method="filterNode"
            node-key="id"
            highlight-current
            @node-click="handleNodeClick"
          >
            <template #default="{ node, data }">
              <span class="subject-node">
                <span>{{ data.code }} - {{ data.label }}</span>
                <span class="subject-balance" :class="data.balance >= 0 ? 'positive' : 'negative'">
                  {{ data.balance ? data.balance.toFixed(2) : '' }}
                </span>
              </span>
            </template>
          </el-tree>
        </el-card>
      </el-col>

      <!-- 右侧：账务处理 -->
      <el-col :span="18">
        <!-- 账务概览 -->
        <el-card class="overview-card">
          <el-row :gutter="20">
            <el-col :span="8">
              <el-statistic title="本期收入" :value="overview.income" :precision="2">
                <template #prefix>¥</template>
              </el-statistic>
            </el-col>
            <el-col :span="8">
              <el-statistic title="本期支出" :value="overview.expense" :precision="2">
                <template #prefix>¥</template>
              </el-statistic>
            </el-col>
            <el-col :span="8">
              <el-statistic 
                title="本期利润" 
                :value="overview.profit"
                :precision="2"
                :value-style="overview.profit >= 0 ? { color: '#67C23A' } : { color: '#F56C6C' }"
              >
                <template #prefix>¥</template>
              </el-statistic>
            </el-col>
          </el-row>
        </el-card>

        <!-- 凭证列表 -->
        <el-card class="voucher-card">
          <template #header>
            <div class="card-header">
              <span>凭证列表</span>
              <div class="header-actions">
                <el-date-picker
                  v-model="voucherMonth"
                  type="month"
                  placeholder="选择月份"
                  format="YYYY年MM月"
                />
              </div>
            </div>
          </template>

          <el-table :data="vouchers" style="width: 100%">
            <el-table-column type="expand">
              <template #default="props">
                <div class="voucher-detail">
                  <el-table :data="props.row.entries" border>
                    <el-table-column prop="subject" label="科目" width="200" />
                    <el-table-column prop="debit" label="借方" width="150">
                      <template #default="{ row }">
                        <span v-if="row.debit">¥{{ row.debit.toFixed(2) }}</span>
                      </template>
                    </el-table-column>
                    <el-table-column prop="credit" label="贷方" width="150">
                      <template #default="{ row }">
                        <span v-if="row.credit">¥{{ row.credit.toFixed(2) }}</span>
                      </template>
                    </el-table-column>
                    <el-table-column prop="memo" label="摘要" />
                  </el-table>
                </div>
              </template>
            </el-table-column>

            <el-table-column prop="date" label="日期" width="120" />
            <el-table-column prop="number" label="凭证号" width="120" />
            <el-table-column prop="summary" label="摘要" show-overflow-tooltip />
            <el-table-column prop="amount" label="金额" width="150">
              <template #default="{ row }">
                ¥{{ row.amount.toFixed(2) }}
              </template>
            </el-table-column>
            <el-table-column prop="status" label="状态" width="100">
              <template #default="{ row }">
                <el-tag :type="getStatusType(row.status)">
                  {{ getStatusText(row.status) }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="200" fixed="right">
              <template #default="{ row }">
                <el-button-group>
                  <el-button 
                    type="primary" 
                    link
                    @click="editVoucher(row)"
                  >
                    编辑
                  </el-button>
                  <el-button 
                    type="success" 
                    link
                    :disabled="row.status !== 'draft'"
                    @click="postVoucher(row)"
                  >
                    过账
                  </el-button>
                  <el-button 
                    type="danger" 
                    link
                    :disabled="row.status === 'posted'"
                    @click="deleteVoucher(row)"
                  >
                    删除
                  </el-button>
                </el-button-group>
              </template>
            </el-table-column>
          </el-table>

          <div class="pagination-container">
            <el-pagination
              v-model:current-page="currentPage"
              v-model:page-size="pageSize"
              :total="total"
              :page-sizes="[10, 20, 50, 100]"
              layout="total, sizes, prev, pager, next, jumper"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            />
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 新建/编辑凭证对话框 -->
    <el-dialog
      v-model="voucherDialogVisible"
      :title="editingVoucher ? '编辑凭证' : '新建凭证'"
      width="800px"
    >
      <el-form
        ref="voucherFormRef"
        :model="voucherForm"
        :rules="voucherRules"
        label-position="top"
      >
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="日期" prop="date">
              <el-date-picker
                v-model="voucherForm.date"
                type="date"
                placeholder="选择日期"
                class="w-full"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="凭证号" prop="number">
              <el-input v-model="voucherForm.number" placeholder="系统自动生成" disabled />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="附件数" prop="attachments">
              <el-input-number
                v-model="voucherForm.attachments"
                :min="0"
                class="w-full"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="摘要" prop="summary">
          <el-input v-model="voucherForm.summary" placeholder="请输入凭证摘要" />
        </el-form-item>

        <div class="entries-table">
          <div class="table-header">
            <h4>分录明细</h4>
            <el-button type="primary" link @click="addEntry">
              添加分录
            </el-button>
          </div>

          <el-table :data="voucherForm.entries" border>
            <el-table-column label="科目" width="250">
              <template #default="{ row, $index }">
                <el-select
                  v-model="row.subject"
                  placeholder="选择科目"
                  filterable
                  class="w-full"
                >
                  <el-option
                    v-for="subject in flatSubjects"
                    :key="subject.id"
                    :label="`${subject.code} - ${subject.label}`"
                    :value="subject.id"
                  />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column label="借方" width="200">
              <template #default="{ row }">
                <el-input-number
                  v-model="row.debit"
                  :precision="2"
                  :step="100"
                  :min="0"
                  class="w-full"
                  @change="calculateBalance"
                />
              </template>
            </el-table-column>
            <el-table-column label="贷方" width="200">
              <template #default="{ row }">
                <el-input-number
                  v-model="row.credit"
                  :precision="2"
                  :step="100"
                  :min="0"
                  class="w-full"
                  @change="calculateBalance"
                />
              </template>
            </el-table-column>
            <el-table-column label="摘要">
              <template #default="{ row }">
                <el-input v-model="row.memo" placeholder="请输入摘要" />
              </template>
            </el-table-column>
            <el-table-column width="50">
              <template #default="{ $index }">
                <el-button 
                  type="danger" 
                  link
                  @click="removeEntry($index)"
                >
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>

          <div class="entries-summary">
            <div class="summary-item">
              <span>借方合计：</span>
              <span class="amount">¥{{ totalDebit.toFixed(2) }}</span>
            </div>
            <div class="summary-item">
              <span>贷方合计：</span>
              <span class="amount">¥{{ totalCredit.toFixed(2) }}</span>
            </div>
            <div class="summary-item">
              <span>差额：</span>
              <span 
                class="amount" 
                :class="balance === 0 ? '' : 'error'"
              >
                ¥{{ balance.toFixed(2) }}
              </span>
            </div>
          </div>
        </div>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="voucherDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitVoucher" :disabled="balance !== 0">
            保存
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  DocumentAdd,
  Refresh,
  Search
} from '@element-plus/icons-vue'

// 会计科目树
const subjectTree = ref([
  {
    id: 1,
    code: '1001',
    label: '库存现金',
    balance: 50000.00
  },
  {
    id: 2,
    code: '1002',
    label: '银行存款',
    balance: 150000.00,
    children: [
      {
        id: 21,
        code: '1002001',
        label: '工商银行',
        balance: 80000.00
      },
      {
        id: 22,
        code: '1002002',
        label: '建设银行',
        balance: 70000.00
      }
    ]
  },
  {
    id: 3,
    code: '2001',
    label: '应付账款',
    balance: -30000.00
  }
])

// 扁平化的科目列表
const flatSubjects = computed(() => {
  const result = []
  const flatten = (nodes) => {
    nodes.forEach(node => {
      result.push(node)
      if (node.children) {
        flatten(node.children)
      }
    })
  }
  flatten(subjectTree.value)
  return result
})

// 科目树配置
const defaultProps = {
  children: 'children',
  label: 'label'
}

// 科目搜索关键词
const subjectKeyword = ref('')
const subjectTreeRef = ref(null)

// 监听关键词变化
watch(subjectKeyword, (val) => {
  subjectTreeRef.value?.filter(val)
})

// 科目树过滤方法
const filterNode = (value, data) => {
  if (!value) return true
  const searchStr = `${data.code} ${data.label}`.toLowerCase()
  return searchStr.includes(value.toLowerCase())
}

// 账务概览数据
const overview = ref({
  income: 256789.45,
  expense: 198234.67,
  profit: 58554.78
})

// 凭证列表数据
const vouchers = ref([
  {
    date: '2025-03-14',
    number: 'PZ202503140001',
    summary: '收到运费',
    amount: 5000.00,
    status: 'posted',
    entries: [
      {
        subject: '银行存款',
        debit: 5000.00,
        credit: null,
        memo: '收到客户运费'
      },
      {
        subject: '主营业务收入',
        debit: null,
        credit: 5000.00,
        memo: '确认运输收入'
      }
    ]
  }
])

// 分页参数
const currentPage = ref(1)
const pageSize = ref(20)
const total = ref(100)

// 当前选择的月份
const voucherMonth = ref(new Date())

// 凭证表单对话框
const voucherDialogVisible = ref(false)
const voucherFormRef = ref(null)
const editingVoucher = ref(null)

// 凭证表单数据
const voucherForm = ref({
  date: new Date(),
  number: '',
  summary: '',
  attachments: 0,
  entries: [
    {
      subject: '',
      debit: null,
      credit: null,
      memo: ''
    }
  ]
})

// 凭证表单验证规则
const voucherRules = {
  date: [{ required: true, message: '请选择日期', trigger: 'change' }],
  summary: [{ required: true, message: '请输入摘要', trigger: 'blur' }]
}

// 计算借贷方合计和差额
const totalDebit = computed(() => {
  return voucherForm.value.entries.reduce((sum, entry) => sum + (entry.debit || 0), 0)
})

const totalCredit = computed(() => {
  return voucherForm.value.entries.reduce((sum, entry) => sum + (entry.credit || 0), 0)
})

const balance = computed(() => {
  return totalDebit.value - totalCredit.value
})

// 获取状态类型
const getStatusType = (status) => {
  const typeMap = {
    'draft': 'info',
    'posted': 'success',
    'voided': 'danger'
  }
  return typeMap[status] || 'info'
}

// 获取状态文本
const getStatusText = (status) => {
  const textMap = {
    'draft': '草稿',
    'posted': '已过账',
    'voided': '已作废'
  }
  return textMap[status] || '未知'
}

// 处理科目点击
const handleNodeClick = (data) => {
  console.log('选中科目:', data)
}

// 添加科目
const addSubject = () => {
  ElMessage.info('打开添加科目表单')
}

// 刷新数据
const refreshData = () => {
  ElMessage.success('数据已更新')
}

// 处理分页大小变化
const handleSizeChange = (size) => {
  pageSize.value = size
  // 重新加载数据
}

// 处理页码变化
const handleCurrentChange = (page) => {
  currentPage.value = page
  // 重新加载数据
}

// 新建凭证
const createVoucher = () => {
  editingVoucher.value = null
  voucherForm.value = {
    date: new Date(),
    number: '',
    summary: '',
    attachments: 0,
    entries: [
      {
        subject: '',
        debit: null,
        credit: null,
        memo: ''
      }
    ]
  }
  voucherDialogVisible.value = true
}

// 编辑凭证
const editVoucher = (voucher) => {
  editingVoucher.value = voucher
  voucherForm.value = JSON.parse(JSON.stringify(voucher))
  voucherDialogVisible.value = true
}

// 添加分录
const addEntry = () => {
  voucherForm.value.entries.push({
    subject: '',
    debit: null,
    credit: null,
    memo: ''
  })
}

// 删除分录
const removeEntry = (index) => {
  voucherForm.value.entries.splice(index, 1)
}

// 计算借贷方平衡
const calculateBalance = () => {
  // 自动计算已在计算属性中实现
}

// 提交凭证
const submitVoucher = async () => {
  if (!voucherFormRef.value) return
  
  try {
    await voucherFormRef.value.validate()
    // 提交表单数据
    ElMessage.success('凭证保存成功')
    voucherDialogVisible.value = false
  } catch (error) {
    console.error('表单验证失败:', error)
  }
}

// 过账凭证
const postVoucher = (voucher) => {
  ElMessageBox.confirm(
    '确认过账该凭证？过账后将不能修改',
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(() => {
    voucher.status = 'posted'
    ElMessage.success('凭证已过账')
  }).catch(() => {})
}

// 删除凭证
const deleteVoucher = (voucher) => {
  ElMessageBox.confirm(
    '确认删除该凭证？',
    '警告',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'danger'
    }
  ).then(() => {
    // 执行删除操作
    ElMessage.success('凭证已删除')
  }).catch(() => {})
}
</script>

<style scoped>
.accounting-container {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.header-title {
  display: flex;
  flex-direction: column;
}

.header-title h2 {
  margin: 0;
  font-size: 22px;
  color: #303133;
}

.subtitle {
  font-size: 14px;
  color: #909399;
  margin-top: 5px;
}

.subject-card,
.overview-card,
.voucher-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.subject-node {
  flex: 1;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-right: 8px;
}

.subject-balance {
  font-family: monospace;
}

.subject-balance.positive {
  color: var(--el-color-success);
}

.subject-balance.negative {
  color: var(--el-color-danger);
}

.voucher-detail {
  padding: 20px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.entries-table {
  margin-top: 20px;
}

.table-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.table-header h4 {
  margin: 0;
  color: var(--el-text-color-primary);
}

.entries-summary {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
  gap: 24px;
}

.summary-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.summary-item .amount {
  font-family: monospace;
  font-weight: 500;
}

.summary-item .amount.error {
  color: var(--el-color-danger);
}

.mb-3 {
  margin-bottom: 12px;
}

.w-full {
  width: 100%;
}

:deep(.el-table__expanded-cell) {
  padding: 20px !important;
}
</style>